/*
 * =====================================================================================
 *
 *       Filename:  usb.h
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2010-2-12 8:29:03
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (), 
 *        Company:  
 *
 * =====================================================================================
 */
#include "..\include\usbdev.h"
#include "..\include\bitopt.h"
#include "..\include\serial.h"
#include "..\include\Gpio.h"
#include "..\lib\key.h"
#include "usbvar.h"
#include "usbdes.h"
#include "USBDESCFG.H"
#include "usbdef.h"

#define	KEY_BACK 0x2A			/*  */
#define	KEY_RARROW 0x4f			/*  */
#define	KEY_LARROW 0x50			/*  */

static uint8 idata sendCount=0;
static uint8  idata sendMax=0;
static uint8 idata usb_status=0;
static StruWaitForSend idata waitForSendArr[3];
static int8 idata keyBuf[9];
static int8 idata mouseBuf[5];

void Ep0Send()
{
   
	if(waitForSendArr[0].waitLen>DEVDES_MAXPACKETSZ0)
	{
	 	USBDev_WrEPBuf(0,DEVDES_MAXPACKETSZ0,waitForSendArr[0].waitPoint);
         	waitForSendArr[0].waitPoint+=DEVDES_MAXPACKETSZ0;
     		waitForSendArr[0].waitLen-=DEVDES_MAXPACKETSZ0;
                 
	}
	else
	{
		if(waitForSendArr[0].waitLen!=0)
		{
	 	   USBDev_WrEPBuf(0,waitForSendArr[0].waitLen,waitForSendArr[0].waitPoint);
		  waitForSendArr[0].waitLen=0; 
		}
		else
		{
		 	if(CHKBIT(waitForSendArr[0].status,SENDSTATUS_NEEDZERO))
			{
				USBDev_WrEPBuf(0,0,waitForSendArr[0].waitPoint);
			}
		}
	}
//	Serial_SendArr(waitForSendArr[0].waitPoint,waitForSendArr[0].waitLen);

     

}
void Endpt0_OutInt()
{ 
	uint16 reqLen;
	if(USBDev_RdEndptLastStatus(0)&0x20)
	{
		ep0RxBuf.len = USBDev_RdEndptBuf(0,16,(ep0RxBuf.buf));
     //    Serial_SendArr(ep0RxBuf.buf,ep0RxBuf.len);
		reqLen=(((uint16)(ep0RxBuf.buf[REQBUF_LENHIDX]))<<8)+ep0RxBuf.buf[REQBUF_LENLIDX];
		USBDev_AckSetup();
		USBDev_ClrBuf();
	if(ep0RxBuf.buf[REQBUF_TYPEIDX]&0x80)
	{
		switch(ep0RxBuf.buf[REQBUF_TYPEIDX]&REQSTL_MASKBIT)
		{
			case REQ_STD:
			        
				switch(ep0RxBuf.buf[REQBUF_REQIDX])
				{
					case STDREQ_GETCFG:
						
						break;
					case STDREQ_GETDES:
						switch(ep0RxBuf.buf[REQBUF_VALUEHIDX])
						{
							case DES_DEV:
								
								waitForSendArr[0].waitPoint=DevDes;
								if(DEVDES_LEN<reqLen)
								{
								waitForSendArr[0].waitLen=DEVDES_LEN;
								}
								else
								{
									waitForSendArr[0].waitLen=reqLen;
								}
								break;
							case DES_CFG:
								waitForSendArr[0].waitPoint=CfgDes;
								if(reqLen>sizeof(CfgDes))
								{
								waitForSendArr[0].waitLen
									=sizeof(CfgDes);
								}
								else
								{
								waitForSendArr[0].waitLen
									=reqLen;
								}
								//Serial_Send(sizeof(CfgDes));
								break;
							case DES_STR:
								switch(ep0RxBuf.buf[REQBUF_VALUELIDX])
								{
									case 0:
										waitForSendArr[0].waitPoint=StrDes_LanguageId;
										waitForSendArr[0].waitLen
											=(reqLen<sizeof(StrDes_LanguageId))?reqLen:sizeof(StrDes_LanguageId);
										break;
									case VENDER_STRIDX:
										waitForSendArr[0].waitPoint=StrDes_Vender;
										waitForSendArr[0].waitLen
											=(reqLen<sizeof(StrDes_Vender))?reqLen:sizeof(StrDes_Vender);
										break;
									case DEV_STRIDX:
										waitForSendArr[0].waitPoint=StrDes_Product;
										waitForSendArr[0].waitLen
											=(reqLen<sizeof(StrDes_Product))?reqLen:sizeof(StrDes_Product);
										break;
									case SN_STRIDX:
										waitForSendArr[0].waitPoint=StrDes_SN;
										waitForSendArr[0].waitLen
											=(reqLen<sizeof(StrDes_SN))?reqLen:sizeof(StrDes_SN);
										break;
								}
								break;
							case DES_REPORT:
								switch(ep0RxBuf.buf[REQBUF_IDXLIDX])
								{
									case 0x00:	
										waitForSendArr[0].waitPoint=ReportDes;
										waitForSendArr[0].waitLen
											=(reqLen<sizeof(ReportDes))?reqLen:sizeof(ReportDes);
										break;
									case 0x01:	
										waitForSendArr[0].waitPoint=reportDes_Mouse;
										waitForSendArr[0].waitLen
											=(reqLen<sizeof(reportDes_Mouse))?reqLen:sizeof(reportDes_Mouse);
										break;
										
									default:	
										waitForSendArr[0].waitPoint=reportDes_Mouse;
										waitForSendArr[0].waitLen=0;
										break;


								}
							//	Serial_Send(waitForSendArr[0].waitLen);
					                      // Serial_SendArr(waitForSendArr[0].waitPoint,waitForSendArr[0].waitLen);
								break;



						}
						if(waitForSendArr[0].waitLen%DEVDES_MAXPACKETSZ0==0)
						SETBIT(waitForSendArr[0].status,SENDSTATUS_NEEDZERO);
						SETBIT(waitForSendArr[0].status,SENDSTATUS_BUSY);
						Ep0Send();
						break;
					case STDREQ_GETITF:
						break;
					case STDREQ_GETSTATUS:
						break;
					case STDREQ_SYNCFRM:
						break;
					default:
						break;
			

				}
				break;
			case REQ_CLASS:
				break;
			case REQ_VENDER:
				break;
			case REQ_RES:
				break;
		}
	}// if(ep0RxBuf.buf[0/*RequestAddr.RequestType*/]&0x80)
	else
	{
		switch(ep0RxBuf.buf[REQBUF_TYPEIDX]&REQSTL_MASKBIT)
		{
			
			case REQ_STD:
				switch(ep0RxBuf.buf[REQBUF_REQIDX])
				{
					case STDREQ_CLRFEATURE:
						break;
					case STDREQ_SETADDR:
						USBDev_SetAddr(ep0RxBuf.buf[REQBUF_VALUELIDX]);
						waitForSendArr[0].waitLen=0;
						SETBIT(waitForSendArr[0].status,SENDSTATUS_NEEDZERO);
						Ep0Send();

						break;
					case STDREQ_SETCFG:
						if(ep0RxBuf.buf[REQBUF_VALUELIDX])
						{
						USBDev_SetEpEn();
						SETBIT(usb_status,STATUS_CFGOK);
						}
						SETBIT(waitForSendArr[0].status,SENDSTATUS_NEEDZERO);
						
						Ep0Send();
						break;
					case STDREQ_SETDES:
						break;
					case STDREQ_SETFEATURE:
						break;
					case STDREQ_SETITF:
						break;
					default:
						break;

				}

				break;
			case REQ_CLASS:
				switch(ep0RxBuf.buf[REQBUF_REQIDX])
				{
					case    CLASSREQ_GETREPORT:
						break;
					case    CLASSREQ_GETIDLE:
						break;
					case    CLASSREQ_GETPROTOCOL:
						break;
					case    CLASSREQ_SETREPORT:
						break;
					case    CLASSREQ_SETIDLE:
						SETBIT(waitForSendArr[0].status,SENDSTATUS_NEEDZERO);
						Ep0Send();
						break;
					case    CLASSREQ_SETPROTOCOL:
						break;

				}
				break;
			case REQ_VENDER:
				break;
			case REQ_RES:
				break;
		}
		         	

	}
	}
	else
	{
		ep0RxBuf.len = USBDev_RdEndptBuf(0,16,ep0RxBuf.buf);
		//Serial_SendArr(ep0RxBuf.buf,ep0RxBuf.len);
		USBDev_ClrBuf();
	}
//	Serial_Send(ep0RxBuf.buf[REQTYPEIDX]);



}

void Endpt0_InInt()
{
      USBDev_RdEndptLastStatus(1);
	 Ep0Send();
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Endpt1_OutInt
 *  Description:  
 * =====================================================================================
 */
void Endpt1_OutInt (  )
{
	uint8 Buf[2];
	USBDev_RdEndptLastStatus(2);
	USBDev_RdEndptBuf(2,2,Buf);
	USBDev_ClrBuf();

	Gpio_Out(2,~Buf[1]);	

}		/* -----  end of function Endpt1_OutInt  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Endpt1_InInt
 *  Description:  
 * =====================================================================================
 */
void Endpt1_InInt (  )
{
	USBDev_RdEndptLastStatus(3);
	SETBIT(usb_status,STATUS_EP1RDY);
}		/* -----  end of function Endpt1_InInt  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Endpt2_InInt
 *  Description:  
 * =====================================================================================
 */
void Endpt2_InInt ( ) 
{
	USBDev_RdEndptLastStatus(5);
	SETBIT(usb_status,STATUS_EP2RDY);

}		/* -----  end of function Endpt2_InInt  ----- */

void Endpt2_OutInt ( )
{
	uint8 Buf[2];
	USBDev_RdEndptLastStatus(2);
	USBDev_RdEndptBuf(4,2,Buf);
	USBDev_ClrBuf();
}		/* -----  end of function Endpt2_OutInt  ----- */

void USB_Rst (  )
{

		SETBIT(usb_status,STATUS_EP1RDY);
		SETBIT(usb_status,STATUS_EP2RDY);
//		Serial_Send(usb_status);
}		/* -----  end of function USB_Rst  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  USB_Task
 *  Description:  
 * =====================================================================================
 */
void USB_Task (  )
{
	//Serial_Send(usb_status);
//	Gpio_Out(2,usb_status);
        uint8 retval;	
	if(Key_ChangeChk())
	{
		retval=Key_GetValue()>>4;
		if(retval>=0x08)
		{
			if((usb_status&(STATUS_EP2RDY+STATUS_CFGOK))
					==STATUS_EP2RDY+STATUS_CFGOK)
			{
			mouseBuf[0]=0x01;
			switch(retval)
			{
				
				case 0x08:	
					mouseBuf[1]=0;
					mouseBuf[2]=0;
					mouseBuf[3]=0;
					mouseBuf[4]=0;
					break;
				case 0x09:
					mouseBuf[1]=0x01;
					break;
				case 0x0A:	
					mouseBuf[2]=0xf0;
					break;
				case 0x0C:	
					mouseBuf[2]=0x0f;
			        	break;
				 default:
					break;

			}
			waitForSendArr[2].waitLen=5;
		        waitForSendArr[2].waitPoint=mouseBuf;
			USBDev_WrEPBuf(2,waitForSendArr[2].waitLen,waitForSendArr[2].waitPoint);
  			CLRBIT(usb_status,STATUS_EP2RDY);
			}
		}
		else
		{
                        if((usb_status&(STATUS_EP1RDY+STATUS_CFGOK))
					==STATUS_EP1RDY+STATUS_CFGOK)
			{
			keyBuf[0]=0x01;
			switch(retval)
			{
				case 0x00:	
					keyBuf[3]=0x00;
					break;
				case 0x01:	
					keyBuf[3]=KEY_BACK;
					break;
				case 0x02:	
					keyBuf[3]=KEY_LARROW;
					break;
				case 0x04:	
					keyBuf[3]=KEY_RARROW;
					break;
				default:
					keyBuf[3]=0x00;
					break;
			}
			waitForSendArr[1].waitLen=9;
		        waitForSendArr[1].waitPoint=keyBuf;
			USBDev_WrEPBuf(1,waitForSendArr[1].waitLen,waitForSendArr[1].waitPoint);
  			CLRBIT(usb_status,STATUS_EP1RDY);
			}

                          }
			
		}

	


}		/* -----  end of function USB_Task  ----- */
